package com.yuyou.fn.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.github.wens.mybatisplus.plugins.Page;
import com.google.common.collect.Maps;
import com.yuyou.fn.analyze.service.*;
import com.yuyou.fn.analyze.vo.*;
import com.yuyou.fn.common.constant.SysResourceEnum;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.service.ISmsService;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.*;
import com.yuyou.fn.platform.entity.AreaTeam;
import com.yuyou.fn.platform.entity.BusTeam;
import com.yuyou.fn.platform.entity.SysUser;
import com.yuyou.fn.platform.entity.UserNotifyConfig;
import com.yuyou.fn.platform.permission.DataPermission;
import com.yuyou.fn.platform.service.*;
import com.yuyou.fn.platform.vo.SysResourceVo;
import com.yuyou.fn.platform.vo.SysUserSaveOrUpdateVo;
import com.yuyou.fn.platform.vo.UserNotifyConfigSaveVo;
import com.yuyou.fn.report.vo.RegRelativceQueryVo;
import com.yuyou.fn.settlement.entity.Fee;
import com.yuyou.fn.settlement.entity.MainAccount;
import com.yuyou.fn.settlement.service.IFeeCategoryService;
import com.yuyou.fn.settlement.service.IFeeService;
import com.yuyou.fn.settlement.service.IMainAccountService;
import com.yuyou.fn.settlement.service.ISettlementService;
import com.yuyou.fn.settlement.vo.FeeCategoryTreeMapVo;
import com.yuyou.fn.settlement.vo.FeeQueryVo;
import com.yuyou.fn.settlement.vo.FeeSaveVo;
import com.yuyou.fn.settlement.vo.MainAccountQueryVo;
import com.yuyou.fn.tradingservice.entity.ServiceMerchant;
import com.yuyou.fn.tradingservice.service.IServiceMerchantService;
import com.yuyou.fn.tradingservice.vo.ServiceMerchantVo;
import com.yuyou.fn.tradingservice.vo.SysUserLoginSuccessVo;
import com.yuyou.fn.vo.UserConfigVo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * Created by itachi on 2017/04/05.
 */
@Controller
@RequestMapping("/api/mobile")
public class AdminMTController extends ApiBaseController {

    @Resource
    private IIndexStatisticsService indexStatisticsService;

    @Resource
    private IDataStatisticsService dataStatisticsService;

    @Resource
    private IBaseGradeService baseGradeService;

    @Resource
    private IServiceMerchantService serviceMerchantService;

    @Resource
    private ICaptchaService captchaService;

    @Resource
    private IAccessTokenService accessTokenService;

    @Resource
    private ISmsService smsService;

    @Resource
    private IBusTeamService busTeamService;

    @Resource
    private IPeriodService periodService;

    @Resource
    private ISysResourceService sysResourceService;

    @Resource
    private IAreaTeamService areaTeamService;

    @Resource
    private ICampusService campusService;

    @Resource
    private IFeeService feeService;

    @Resource
    private IBaseSubjectService baseSubjectService;

    @Resource
    private IStudentService studentService;

    @Resource
    private IStudentRefundService studentRefundService;

    @Resource
    private IStudentSchoolService studentSchoolService;

    @Resource
    private IStudentRegService studentRegService;

    @Resource
    private IProductService productService;

    @Resource
    private IFeeCategoryService feeCategoryService;

    @Resource
    private IMainAccountService mainAccountService;

    @Resource
    private IProductStatisticsService productStatisticsService;

    @Resource
    private IGradeAndSubjectStatisticsService gradeAndSubjectStatisticsService;

    @Resource
    private IBusinessStatisticsService businessStatisticsService;

    @Resource
    private ISiteConfigService siteConfigService;

    @Resource
    private ISettlementService settlementService;

    @Resource
    private IUserNotifyConfigService userNotifyConfigService;

    @ApiOperation("账号密码登陆")
    @RequestMapping(value = "/login", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<SysUserLoginSuccessVo> login(@RequestParam(value = "username") String username, @RequestParam("password") String password, @RequestParam(value = "captchaCode", required = false) String captchaCode, @RequestParam(value = "u", required = false) String uid, HttpServletRequest request, HttpSession session) {
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return ReturnResult.fail("用户名和密码不能为空");
        }
        SysUser user = sysUserService.login(username, password);
        if (user == null) {
            Long failTime = captchaService.opsStat(username, "login");
            HashMap<String, Object> ret = Maps.newHashMap();
            ret.put("failTime", failTime);
            return ReturnResult.fail("用户名或密码不正确", ret);
        }
        if (user.getStatus() == 0) {
            return ReturnResult.fail("你的帐号被禁用，暂时不能登录");
        }

        /*登录查找是否自动注册为商家*/
        ServiceMerchant serviceMerchant = serviceMerchantService.findById(user.getUserId());
        if (serviceMerchant == null) {
            serviceMerchant = new ServiceMerchant();
            BeanUtils.copyProperties(serviceMerchant, user);
            serviceMerchant.setMerchantId(user.getUserId());
            serviceMerchant.setMerchantName(user.getUsername());
            serviceMerchant.setMerchantPassword(user.getPassword());
            serviceMerchant.setHeadImageUrl(user.getAvatarUrl());
            serviceMerchant.setCreateTime(TimeUtils.now());
            serviceMerchant.setUpdateTime(TimeUtils.now());
            serviceMerchant.setStatus(3);//已有用户不需审核
            serviceMerchant.setRoleType(user.getUserType());
            serviceMerchantService.insertSelective(serviceMerchant);
        }

        if (captchaService.needVerifyCode(username, "login", 3)) {
            captchaService.verifyCode(captchaCode);
            captchaService.cleanOptStat(username, "login");
        }
        String accessToken = accessTokenService.generateToken(user.getUserId() ,user.getRealName(),"sysUser" );
        return ReturnResult.success(new SysUserLoginSuccessVo(accessToken, user));
    }

    @ApiOperation("通过手机验证码修改密码")
    @RequestMapping(value = "/changePasswordByCode", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<String> changePasswordByCode(@RequestParam(value = "code") String code, @RequestParam(value = "phoneNo") String phoneNo, @RequestParam(value = "newPasswordMd5") String newPasswordMd5, HttpServletRequest request) {
        //serviceMerchantService.auditMerchants(merchantIds,status);
        boolean ok = smsService.validate(phoneNo, code);
        if (ok) {
            serviceMerchantService.changeMerchantPassword(phoneNo, newPasswordMd5);
        } else {
            return ReturnResult.fail("短信验证码不正确");
        }
        return ReturnResult.success("ok");
    }


    @ApiOperation("获取区域期列表")
    @RequestMapping(value = "/n/periodListForAreaTeam" ,method = { RequestMethod.GET ,RequestMethod.POST })
    @ResponseBody
    public ReturnResult<List<Period>> periodListForAreaTeam(@RequestParam("areaTeamId") Long areaTeamId) {
        List<Period> list = periodService.findNearPeriod(areaTeamId, 10);
        return ReturnResult.success(list);
    }


    @ApiOperation("获取配置(权限)")
    @RequestMapping(value = "/n/config", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<UserConfigVo> config(HttpServletRequest request) {

        SysUser user = getUser(request);

        DataPermission dataPermission = getDataPermission(request);

        List<SysResourceVo> resourceList = sysResourceService.findResourceByUserIdRootIdFromCache(user.getUserId(), SysResourceEnum.MOBILE.id);

        List<Long> areaTeamIds  = dataPermission.getAreaTeamIds();
        List<Long> busTeamIds  = dataPermission.getBusTeamIds();
        List<Long> campusIds = dataPermission.getCampusIds() ;
        List<AreaTeam> areaTeamList = areaTeamService.findByIds(areaTeamIds);
        List<BusTeam> busTeamList = busTeamService.findByIds(busTeamIds);
        List<Campus> campusList=campusService.findByIds(campusIds);

        List<BaseGrade> gradeList = baseGradeService.findAllFromCache();
        Iterator<BaseGrade> baseGradeIterator=gradeList.iterator();
        while (baseGradeIterator.hasNext()){
            BaseGrade baseGrade=baseGradeIterator.next();
            baseGradeIterator.remove();
            gradeList.add(baseGrade);
            break;
        }

        List<BaseSubject> subjectList = baseSubjectService.findAllFromCache();

        List<MainAccount> mainAccountList = serviceMerchantService.ownMainAccount(user);

        UserConfigVo userConfigVo = new UserConfigVo();
        userConfigVo.setUserType(user.getUserType());
        userConfigVo.setBusTeamList(busTeamList);
        userConfigVo.setAreaTeamList(areaTeamList);
        userConfigVo.setResourceList(resourceList);
        userConfigVo.setGradeList(gradeList);
        userConfigVo.setSubjectList(subjectList);
        userConfigVo.setCampusList(campusList);
        userConfigVo.setMainAccountList(mainAccountList);
        return ReturnResult.success(userConfigVo);
    }


    @ApiOperation("注册")
    @RequestMapping(value = "/register", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<String> register(@ApiParam(value = "手机验证码", required = true) @RequestParam(value = "code") String code, @ModelAttribute ServiceMerchantVo serviceMerchantvo, HttpServletRequest request,
                                         HttpSession session) {
        if (serviceMerchantvo.getRoleType() == null || StringUtils.isEmpty(serviceMerchantvo.getPhoneNo()) || StringUtils.isEmpty(serviceMerchantvo.getMerchantPassword()) || StringUtils.isEmpty(serviceMerchantvo.getMerchantName())) {
            return ReturnResult.fail("缺乏必填参数");
        }
        SysUser sysUser=sysUserService.findByPhoneNo(serviceMerchantvo.getPhoneNo());
        if (sysUser!=null){
            return ReturnResult.fail("该手机号已存在用户，不可注册");
        }
        boolean ok = smsService.validate(serviceMerchantvo.getPhoneNo(), code);
        if (ok) {
            SysUser user = sysUserService.findByUserName(serviceMerchantvo.getMerchantName());
            if (user != null) {
                return ReturnResult.fail("该用户名已经存在，请直接登录");
            }

            Long count=serviceMerchantService.countByPhoneNoAndStatus(serviceMerchantvo.getPhoneNo(),0);
            if (count>0){
                return ReturnResult.fail("该手机号存在待审核的商家，不可重复提交");
            }

            if (serviceMerchantvo.getRoleType() == 2) {//业务组检查名称是否存在
                BusTeam busTeam = busTeamService.findByAreaTeamIdAndBusName(serviceMerchantvo.getBelongAreaTeamId(), serviceMerchantvo.getBelongBusTeamName());
                if (busTeam != null) {
                    throw new BusException("该业务组名称已存在，注册申请失败");
                }
            }
            if (serviceMerchantvo.getRoleType() == 3) {//业务组检查名称是否存在
                Teacher teacher =teacherService.findTeacherByIdNo(serviceMerchantvo.getIdNo());
                if (teacher != null) {
                    throw new BusException("该身份证已存在，注册申请失败");
                }
            }

            serviceMerchantvo.setStatus(0);//新注册未审核
            serviceMerchantService.save(serviceMerchantvo);
            return ReturnResult.success("注册提交成功，请等待管理员审核，谢谢！");
        } else {
            return ReturnResult.fail("验证码校验失败");
        }
    }





    @ApiOperation("预收看板")
    @RequestMapping(value = "/n/findAdvanceBlock", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<AdvanceBlockVo>> findBlockVo(@RequestParam(value = "subjectIds",required = false)String subjectIds,@RequestParam("areaTeamId")Long areaTeamId,@RequestParam(value = "periodIds") String periodIds, @RequestParam(value = "busTeamIds",required = false)String busTeamIds,@RequestParam(value = "gradeIds",required = false)String gradeIds,@RequestParam(value = "startDate",required = false)Date startDate,@RequestParam(value = "endDate",required = false)Date endDate,HttpServletRequest request) {
        if (endDate==null){
            endDate=TimeUtils.changeOneDateLastTime(new Date());
        }

        DataPermission dataPermission=this.getDataPermission(request);
        List<AdvanceBlockVo> advanceBlockVoList=indexStatisticsService.findAdvanceBlock(dataPermission,areaTeamId,Utils.toLongIds(busTeamIds),Utils.toLongIds(periodIds),Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds),startDate,endDate);
        return ReturnResult.success(advanceBlockVoList);
    }

    @ApiOperation("保存更新系统用户")
    @RequestMapping(value = "/n/saveOrUpdateSysUser", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<SysUserSaveOrUpdateVo> saveOrUpdateSysUser(SysUserSaveOrUpdateVo sysUserSaveOrUpdateVo, HttpServletRequest request) {
        //sysUserSaveOrUpdateVo.setAreaTeamId(getUser(request).getAreaTeamId());
        SysUser user = getUser(request);
        sysUserSaveOrUpdateVo.setUserId(user.getUserId());
        sysUserSaveOrUpdateVo.setUsername(user.getUsername());
        sysUserService.saveOrUpdateSysUser(sysUserSaveOrUpdateVo);
        return ReturnResult.success("Ok");
    }

    @ApiOperation("修改密码")
    @RequestMapping(value = "/n/changePassword", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Void> changeMyPassword(@RequestParam("oldPassword") String oldPassword, @RequestParam("newPassword") String newPassword, HttpServletRequest request) {
        SysUser user = getUser(request);
        sysUserService.changePassword(user.getUserId(), oldPassword, newPassword);

        return ReturnResult.success("OK");
    }

    @ApiOperation("生源看板")
    @RequestMapping(value = "/n/findStudentStateBlock", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<StudentStateBlockVo>> findStudentStateBlock(@RequestParam("areaTeamId")Long areaTeamId,@RequestParam(value = "periodIds") String periodIds, @RequestParam(value = "busTeamIds",required = false)String busTeamIds,@RequestParam(value = "gradeIds",required = false)String gradeIds,@RequestParam(value = "subjectIds",required = false)String subjectIds,@RequestParam(value = "startDate",required = false)Date startDate,@RequestParam(value = "endDate",required = false)Date endDate,HttpServletRequest request) {
        if (endDate==null){
            endDate=TimeUtils.changeOneDateLastTime(new Date());
        }

        DataPermission dataPermission=this.getDataPermission(request);
        List<StudentStateBlockVo> studentStateBlockVoList=indexStatisticsService.findStudentStateBlock(dataPermission,areaTeamId,Utils.toLongIds(busTeamIds),Utils.toLongIds(periodIds),Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds),startDate,endDate);
        return ReturnResult.success(studentStateBlockVoList);
    }

    @ApiOperation("科数看板")
    @RequestMapping(value = "/n/findBranchNumBlockVo", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<BranchNumBlockVo>> findBranchNumBlockVo(@RequestParam("areaTeamId")Long areaTeamId,@RequestParam(value = "periodIds") String periodIds, @RequestParam(value = "busTeamIds",required = false)String busTeamIds,@RequestParam(value = "gradeIds",required = false)String gradeIds,@RequestParam(value = "subjectIds",required = false)String subjectIds,@RequestParam(value = "startDate",required = false)Date startDate,@RequestParam(value = "endDate",required = false)Date endDate,HttpServletRequest request) {
        if (endDate==null){
            endDate=TimeUtils.changeOneDateLastTime(new Date());
        }
        DataPermission dataPermission=this.getDataPermission(request);
        List<BranchNumBlockVo> branchNumBlockVoList=indexStatisticsService.findBranchNumBlockVo(dataPermission,areaTeamId,Utils.toLongIds(busTeamIds),Utils.toLongIds(periodIds),Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds),startDate,endDate);
        return ReturnResult.success(branchNumBlockVoList);
    }

    @ApiOperation("续读分析")
    @RequestMapping(value = "/n/findGradeCompletionVoList", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Page<GradeCompletionRateVo>> findGradeCompletionVoList(@RequestParam(value = "areaTeamId")long areaTeamId,@ModelAttribute RegRelativceQueryVo regRelativceQueryVo,@RequestParam(value = "periodIds") String periodIds, @RequestParam(value = "busTeamIds",required = false)String busTeamIds, @RequestParam(value = "gradeIds",required = false)String gradeIds,@RequestParam(value = "subjectIds",required = false)String subjectIds,HttpServletRequest request) {
        regRelativceQueryVo.setRecordChargingStatus(2);
        //regRelativceQueryVo.setBigRecordLectureNum(5);
        List<Long> busTeamIdList=Utils.toLongIds(busTeamIds);
        if (busTeamIdList.size()<=0){
            busTeamIdList=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),this.getUserId(request));
        }
      /*  List<Long> baseGradeIdList=Utils.toLongIds(gradeIds);
        if (baseGradeIdList.size()<=0){
            List<BaseGrade> baseGradeList=baseGradeService.findAllFromCache();
            baseGradeIdList= BeanUtils.toList(baseGradeList,"gradeId");
        }*/

        List<GradeCompletionRateVo> list = indexStatisticsService.findGradeCompletionVoList(areaTeamId,busTeamIdList,Utils.toLongIds(periodIds),Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds));
        return ReturnResult.success(list);
    }


    @ApiOperation("通过电话号码/名字/手机查询学生是否存在")
    @RequestMapping(value = "/n/searchStudent", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Page<Student>> searchStudent(@RequestParam("keyword") String keyword , @RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageSize", defaultValue = "20") int pageSize, HttpServletRequest request) {
        Page<Student> studentList = studentService.findStudentByKeyword(keyword, pageNo, pageSize);
        return ReturnResult.success(studentList);
    }



    @ApiOperation("获取学生详细信息")
    @RequestMapping(value = "/n/studentDetail", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<StudentDetailVo> getStudentDetail(@RequestParam("studentId") Long studentId) {
        StudentDetailVo studentDetail = studentService.findStudentDetailByStudentId(studentId);
        return ReturnResult.success(studentDetail);
    }
    @ApiOperation("在读班级信息")
    @RequestMapping(value = "/n/studentReadClassList", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    private ReturnResult<List<StudentRegDetailVo>> studentReadClassList(@RequestParam(value = "studentId") Long studentId){
        StudentRegQueryVo studentRegQueryVo = new StudentRegQueryVo();
        studentRegQueryVo.setStudentId(studentId);
        studentRegQueryVo.setRegStatus(0);
        List<StudentReg> studentRegList = studentRegService.findStudentRegQuery(studentRegQueryVo);
        List<StudentRegDetailVo> regDetailVoList = studentRegService.toStudentRegDetailVo(studentRegList);
        return ReturnResult.success(regDetailVoList);
    }



    @ApiOperation("审核费用")
    @RequestMapping(value = "/n/auditingFee" ,method = { RequestMethod.GET ,RequestMethod.POST })
    @ResponseBody
    public ReturnResult<Page<Fee>> auditingFee(@RequestParam("feeId") Long feeId ,@RequestParam("status") Integer status) {
        feeService.auditingFee( feeId , status );
        return ReturnResult.success();
    }





    @ApiOperation("退款申请列表")
    @RequestMapping("/n/showStudentRefundList")
    @ResponseBody
    public ReturnResult<Page<StudentRefund>> showStudentRefundList(StudentRefundQueryVo studentRefundQueryVo, @RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageSize", defaultValue = "20") int pageSize, HttpServletRequest request) {
        DataPermission dataPermission = getDataPermission(request);
        if (studentRefundQueryVo.getEndAuditTime()!=null){
            studentRefundQueryVo.setEndAuditTime(TimeUtils.changeOneDateLastTime(studentRefundQueryVo.getEndAuditTime()));
        }
        if (studentRefundQueryVo.getEndPayTime()!=null){
            studentRefundQueryVo.setEndPayTime(TimeUtils.changeOneDateLastTime(studentRefundQueryVo.getEndPayTime()));
        }
        if (studentRefundQueryVo.getEndCreateTime()!=null){
            studentRefundQueryVo.setEndCreateTime(TimeUtils.changeOneDateLastTime(studentRefundQueryVo.getEndCreateTime()));
        }
        if (studentRefundQueryVo.getEndDate()!=null){
            studentRefundQueryVo.setEndDate(TimeUtils.changeOneDateLastTime(studentRefundQueryVo.getEndDate()));
        }
        Page<StudentRefund> page = studentRefundService.findStudentRefundList(studentRefundQueryVo,dataPermission, pageNo, pageSize);
        return ReturnResult.success(page);
    }

    @ApiOperation("退款申请详情")
    @RequestMapping(value = "/n/studentRefundDetail", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<StudentRefund> studentRefundDetail(@RequestParam("studentRefundId") Long studentRefundId) {
        StudentRefund studentRefund = studentRefundService.findById(studentRefundId);
        return ReturnResult.success(studentRefund);
    }
    @ApiOperation("修改退款申请")
    @RequestMapping("/n/changeStudentRefundStatus")
    @ResponseBody
    public ReturnResult<Void> changeStudentRefundStatus(@RequestParam("studentRefundId") Long studentRefundId , @RequestParam("status") Integer status ,@RequestParam("returnResult") String returnResult,HttpServletRequest request ) {
        studentRefundService.changeStatus(studentRefundId,status,returnResult,getCurrentSysPrincipal());
        return ReturnResult.success("OK");
    }


    @ApiOperation("费用列表")
    @RequestMapping(value = "/n/feeList" ,method = { RequestMethod.GET ,RequestMethod.POST })
    @ResponseBody
    public ReturnResult<Page<Fee>> feeList(FeeQueryVo feeQueryVo , @RequestParam(value = "pageNo" ,defaultValue = "1") int pageNo, @RequestParam(value = "pageSize" ,defaultValue = "20") int pageSize, HttpServletRequest request ) {
        if(feeQueryVo.getEndDate() != null ){
            feeQueryVo.setEndDate(DateUtils.addDays(feeQueryVo.getEndDate() , 1 ));
        }
        Page<Fee> page = feeService.findFeeByQuery(feeQueryVo, pageNo, pageSize);
        return ReturnResult.success(page);
    }



    @ApiOperation("成本录入")
    @RequestMapping(value = "/n/saveFee" ,method = { RequestMethod.GET ,RequestMethod.POST })
    @ResponseBody
    public ReturnResult<Page<Fee>> saveFee(FeeSaveVo feeSaveVo) {
        feeService.saveFee( feeSaveVo );
        return ReturnResult.success();
    }

    @ApiOperation("所有主体账户分页列表")
    @RequestMapping(value = "/n/allMainAccountPageWithoutStudent" ,method = { RequestMethod.GET ,RequestMethod.POST })
    @ResponseBody
    public ReturnResult<Page<MainAccount>> allMainAccountPageWithoutStudent(@ModelAttribute MainAccountQueryVo mainAccountQueryVo,@RequestParam("pageNo")int pageNo, @RequestParam("pageSize") int pageSize) {
        Page<MainAccount> page = mainAccountService.findMainAccountPageWithoutStudent(mainAccountQueryVo,pageNo,pageSize);
        return ReturnResult.success(page);
    }

    @ApiOperation("获取基础产品列表")
    @RequestMapping(value = "/n/baseProductList", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<Product>> baseProductList(HttpServletRequest request) {
        DataPermission dataPermission = getDataPermission(request);
        List<Product> list = productService.findBaseProductForUse(dataPermission);
        return ReturnResult.success(list);
    }


    @ApiOperation("用户可选的主体")
    @RequestMapping(value = "/n/ownMainCount", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<MainAccount>> ownMainCount(HttpServletRequest request) {
        SysUser user = getUser(request);
        List<MainAccount> mainAccountList = serviceMerchantService.ownMainAccount(user);
        return ReturnResult.success(mainAccountList);
    }



    @ApiOperation("成本类型树形结构")
    @RequestMapping(value = "/n/feeCategoryTreeMap" ,method = { RequestMethod.GET ,RequestMethod.POST })
    @ResponseBody
    public ReturnResult<List<FeeCategoryTreeMapVo> > feeCategoryTreeMap() {
        List<FeeCategoryTreeMapVo> feeCategoryTreeMapVoList=feeCategoryService.findTreeCategoryMapVo();
        return ReturnResult.success(feeCategoryTreeMapVoList);
    }



    @ApiOperation("增加或者修改学生信息")
    @RequestMapping(value = "/n/saveOrUpdateStudent", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Void> saveOrUpdateStudent(StudentSaveOrUpdateVo studentSaveOrUpdateVo, @RequestParam("guardianJsonStr") String guardianJsonStr) {
        List<StudentGuardianSaveOrUpdateVo> guardianList = JSON.parseObject(guardianJsonStr, new TypeReference<List<StudentGuardianSaveOrUpdateVo>>() {
        });
        studentSaveOrUpdateVo.setGuardianList(guardianList);
        Long studentId = studentService.saveOrUpdateStudent(studentSaveOrUpdateVo);
        return ReturnResult.success(studentId);
    }
    @ApiOperation("生源学校列表")
    @RequestMapping(value = "/n/studentSchoolList" ,method = { RequestMethod.GET ,RequestMethod.POST })
    @ResponseBody
    public ReturnResult<Page<StudentSchool>> studentSchoolList(@RequestParam(value = "city" , required = false) String city ,@RequestParam(value = "schoolName" , required = false) String schoolName , @RequestParam(value = "pageNo" ,defaultValue = "1") int pageNo, @RequestParam(value = "pageSize" ,defaultValue = "20") int pageSize, HttpServletRequest request ) {
        Page<StudentSchool> page = studentSchoolService.findStudentSchoolForPage(city,schoolName , pageNo, pageSize);
        return ReturnResult.success(page);
    }

    @ApiOperation("区域下业务组产品营收利润")
    @RequestMapping(value = "/n/incomeProfitsOfAreaTeam",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<IncomeProfitsVo> incomeProfitsOfAreaTeam(@RequestParam(value = "areaTeamId")Long areaTeamId,@RequestParam(value = "date")String date,  HttpServletRequest request){
        Date startDate= TimeUtils.firstDateOfMonth(Utils.parseDate(date,"yyyy-MM"));
        Date endDate=TimeUtils.lastDateOfMonth(Utils.parseDate(date,"yyyy-MM"));
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        IncomeProfitsVo incomeProfitsVo=new IncomeProfitsVo();
        SysUser sysUser=this.getUser(request);
        incomeProfitsVo.setProductTeamMap(dataStatisticsService.findProductByAreaTeamId(areaTeamId,startDate,endDate,sysUser));
        incomeProfitsVo.setBusTeamMap(dataStatisticsService.findBusTeamByAreaTeamId(areaTeamId,startDate,endDate));
        return ReturnResult.success(incomeProfitsVo);
    }

    @ApiOperation("业务组主体成本利润统计")
    @RequestMapping(value = "/n/findMainAccountCostAndIncome",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<MainAccountCostAndIncome>> findMainAccountCostAndIncome(@RequestParam(value = "areaTeamId")Long areaTeamId,@RequestParam(value = "startDate") Date startDate,@RequestParam(value = "endDate") Date endDate, HttpServletRequest request){
        SysUser user = getUser(request);
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        List<MainAccount> mainAccountList = dataStatisticsService.findByAreaTeamId(Arrays.asList(areaTeamId),user.getUserId());
        List<MainAccountCostAndIncome> mainAccountCostAndIncomeList=businessStatisticsService.findMainAccountCostAndIncome(startDate,endDate,mainAccountList);
        return ReturnResult.success(mainAccountCostAndIncomeList);
    }

    @ApiOperation("业务组所有一级成本类型统计")
    @RequestMapping(value = "/n/findCostByAllCategory",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<CategoryMainAccountVo>> findCostByCategoryIds(@RequestParam(value = "mainAccountId") Long mainAccountId, @RequestParam(value = "startDate") Date startDate,@RequestParam(value = "endDate") Date endDate, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=getUser(request);
        List<CategoryMainAccountVo> categoryMainAccountVoList=businessStatisticsService.findCostByAllCategory(mainAccountId,startDate,endDate,sysUser);
        return ReturnResult.success(categoryMainAccountVoList);
    }

    @ApiOperation("获得区域列表")
    @RequestMapping(value = "/findAllAreaTeam", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<AreaTeam>> findAllAreaTeam(HttpServletRequest request) {
        List<AreaTeam> areaTeamList = areaTeamService.findAllAreaTeam();
        return ReturnResult.success(areaTeamList);
    }

    @ApiOperation("业务组收入类型统计")
    @RequestMapping(value = "/n/findIncomeByAllCategory",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<CategoryMainAccountVo>> findIncomeByCategoryIds(@RequestParam(value = "mainAccountId") Long mainAccountId, @RequestParam(value = "startDate") Date startDate,@RequestParam(value = "endDate") Date endDate, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=getUser(request);
        List<CategoryMainAccountVo> categoryMainAccountVoList=businessStatisticsService.findIncomeByAllCategory(mainAccountId,startDate,endDate,sysUser);
        return ReturnResult.success(categoryMainAccountVoList);
    }

    @ApiOperation("业务组课程收入  detailType：7班级收入")
    @RequestMapping(value = "/n/mainAccountClassIncome",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Page<ClassIncomeVo>> mainAccountClassIncome(@RequestParam(value = "detailType",defaultValue = "6") Integer detailType,@RequestParam(value = "mainAccountId") Long mainAccountId,@RequestParam(value = "incomeCategoryId") Long incomeCategoryId, @RequestParam(value = "startDate") Date startDate,@RequestParam(value = "endDate") Date endDate, @RequestParam(value = "pageNo")int pageNo,@RequestParam(value = "pageSize")int pageSize,HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        Page<ClassIncomeVo> classIncomeVoPage=businessStatisticsService.classIncomePage(Arrays.asList(mainAccountId),startDate,endDate,pageNo,pageSize);
        return ReturnResult.success(classIncomeVoPage);
    }




    @ApiOperation("获得产品线统计列表")
    @RequestMapping(value = "/n/productStatisticsList",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<ProductCostAndIncomeVo>> productStatisticsList(@RequestParam(value = "areaTeamId")Long areaTeamId,@RequestParam(value = "startDate")Date startDate,@RequestParam(value = "endDate")Date endDate, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=this.getUser(request);
        List<Product> productList=productService.findBaseProductByAreaTeamId(areaTeamId);
        List<ProductCostAndIncomeVo> productCostAndIncomeVoList=productStatisticsService.findProductCostAndIncome(Arrays.asList(areaTeamId),startDate,endDate,productList,sysUser);
        return ReturnResult.success(productCostAndIncomeVoList);
    }

    @ApiOperation("获得单条产品线成本类型统计")
    @RequestMapping(value = "/n/productStatisticsByCategory",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<ProductCostByCategoryVo>> productStatisticsByCategory(@RequestParam(value = "productId") Long productId,@RequestParam(value = "startDate")Date startDate,@RequestParam(value = "endDate")Date endDate, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=this.getUser(request);
        String mainAccountFeeCategory = siteConfigService.getConfigValueFromCache("product_feeCategory");
        List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList = JSONArray.parseArray(mainAccountFeeCategory, FeeCategoryTreeMapVo.class);
        List<ProductCostByCategoryVo> productCostByCategoryVoList=productStatisticsService.findProductCategoryCostByProductId(allFeeCategoryTreeMapVoList,productId,startDate,endDate,sysUser);
        return ReturnResult.success(productCostByCategoryVoList);
    }

    @ApiOperation("获得单条产品营收")
    @RequestMapping(value = "/n/productIncomePage",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Page<ClassIncomeVo>> productIncomePage(@RequestParam(value = "productId") Long productId,@RequestParam(value = "startDate")Date startDate,@RequestParam(value = "endDate")Date endDate,@RequestParam(value = "pageNo")int pageNo,@RequestParam(value = "pageSize")int pageSize, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=this.getUser(request);
        Page<ClassIncomeVo> productIncomeList=productStatisticsService.findClassIncomePageByProductId(productId,startDate,endDate,sysUser,pageNo,pageSize);
        return ReturnResult.success(productIncomeList);
    }



    @ApiOperation("区域年级科目统计")
    @RequestMapping(value = "/n/areaTeamGradeAndSubjectStatistics",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<GradeAndSubjectCostAndIncomeVo>> areaTeamGradeAndSubjectStatistics(@RequestParam(value = "gradeIds",required = false)String gradeIds,@RequestParam(value = "subjectIds",required = false)String subjectIds,  @RequestParam(value = "areaTeamId")long areaTeamId , @RequestParam(value = "startDate")Date startDate,@RequestParam(value = "endDate")Date endDate, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=this.getUser(request);
        List<GradeAndSubjectCostAndIncomeVo> gradeAndSubjectCostAndIncomeVoList=gradeAndSubjectStatisticsService.findCostAndIncomeList(areaTeamId,startDate,endDate,Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds),sysUser);
        return ReturnResult.success(gradeAndSubjectCostAndIncomeVoList);
    }

    @ApiOperation("年级科目详情")
    @RequestMapping(value = "/n/gradeAndSubjectAllCategoryDetail",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<GradeAndSubjectCostByCategoryVo>> gradeAndSubjectAllCategoryDetail(@RequestParam(value = "areaTeamId")Long areaTeamId,@RequestParam(value = "gradeIds")String gradeIds,@RequestParam(value = "subjectIds")String subjectIds, @RequestParam(value = "startDate")Date startDate,@RequestParam(value = "endDate")Date endDate, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=this.getUser(request);
        String mainAccountFeeCategory = siteConfigService.getConfigValueFromCache("grade_subject_feeCategory");
        List<FeeCategoryTreeMapVo> allFeeCategoryTreeMapVoList = JSONArray.parseArray(mainAccountFeeCategory, FeeCategoryTreeMapVo.class);
        List<GradeAndSubjectCostByCategoryVo> gradeAndSubjectCostByCategoryVoList=gradeAndSubjectStatisticsService.findCategoryCostByGradeAndSubject(areaTeamId,allFeeCategoryTreeMapVoList,Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds),startDate,endDate,sysUser);
        return ReturnResult.success(gradeAndSubjectCostByCategoryVoList);
    }

    @ApiOperation("单个年级科目营收")
    @RequestMapping(value = "/n/gradeSubjectIncome",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Page<GradeAndSubjectCostDetailVo>> gradeSubjectIncome(@RequestParam(value = "areaTeamId")Long areaTeamId, @RequestParam(value = "gradeIds")String gradeIds, @RequestParam(value = "subjectIds")String subjectIds, @RequestParam(value = "startDate")Date startDate, @RequestParam(value = "endDate")Date endDate,@RequestParam(value = "pageNo")int pageNo,@RequestParam(value = "pageSize")int pageSize, HttpServletRequest request){
        endDate=TimeUtils.changeOneDateLastTime(endDate);
        SysUser sysUser=this.getUser(request);
        Page<ClassIncomeVo> classIncomeVoPage=gradeAndSubjectStatisticsService.findClassIncomePageByAreaTeamId(areaTeamId,Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds),startDate,endDate,sysUser,pageNo,pageSize);
        return ReturnResult.success(classIncomeVoPage);
    }

    @ApiOperation("业务组满班率")
    @RequestMapping(value = "/n/busTeamfullClassRate",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<BusTeamFullClassRate>> BusTeamfullClassRate(@RequestParam(value = "areaTeamId")Long areaTeamId,@RequestParam(value = "busTeamIds",required = false)String busTeamIds, @RequestParam(value = "periodIds",required = true)String periodIds, @RequestParam(value = "gradeId",required = false)Long gradeId,@RequestParam(value = "subjectIds",required = false)String subjectIds, @RequestParam(value = "gradeIds",required = false)String gradeIds, HttpServletRequest request){
        List<Long> busTeamIdList=Utils.toLongIds(busTeamIds);
        if (busTeamIdList.size()<=0){
            busTeamIdList=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),this.getUserId(request));
        }
        List<Long> gradeIdList=new ArrayList<>();
        if (gradeId!=null){
            gradeIdList=Arrays.asList(gradeId);
        }else {
            gradeIdList=Utils.toLongIds(gradeIds);
        }
        if (gradeIdList.size()<=0){
            throw new BusException("年级必传");
        }

        List<BusTeamFullClassRate> busTeamFullClassRateList=dataStatisticsService.findBusTeamFullClassRate(busTeamIdList,Utils.toLongIds(periodIds),gradeIdList,Utils.toLongIds(subjectIds),areaTeamId);
        return ReturnResult.success(busTeamFullClassRateList);
    }

    @ApiOperation("区域满班率")
    @RequestMapping(value = "/n/areaTeamfullClassRate",method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<AreaTeamFullClassRate>> AreaTeamFullClassRate(@RequestParam(value = "areaTeamId")Long areaTeamId, @ApiParam("单个")@RequestParam(value = "periodIds",required = true)String periodIds,@RequestParam(value = "gradeIds",required = false)String gradeIds, @RequestParam(value = "subjectIds",required = false)String subjectIds,  HttpServletRequest request){

        List<Long> busTeamIdList=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),this.getUserId(request));

        List<AreaTeamFullClassRate> areaTeamFullClassRateList=dataStatisticsService.findAreaTeamFullClassRate(areaTeamId,busTeamIdList,Utils.toLongIds(periodIds),Utils.toLongIds(gradeIds),Utils.toLongIds(subjectIds));
        return ReturnResult.success(areaTeamFullClassRateList);
    }

    @ApiOperation("学生主账户")
    @RequestMapping(value = "/n/studentMainAccount", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<MainAccount> studentMainAccount(@RequestParam("studentId") Long studentId ) {
        MainAccount mainAccount = settlementService.findMainAccount(studentId);
        return ReturnResult.success(mainAccount);
    }

    @ApiOperation("检查登陆是否需要验证码")
    @RequestMapping(value = "/checkNeedCaptcha", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Boolean> checkNeedCaptcha(@RequestParam("username") String username) {
        Boolean ret = null;
        if (captchaService.needVerifyCode(username, "login", 3)) {
            ret = Boolean.TRUE;
        } else {
            ret = Boolean.FALSE;
        }
        return ReturnResult.success(ret);
    }

    @ApiOperation("设置用户邮箱通知数据")
    @RequestMapping(value = "/n/saveOrUpdateEmailNotifyConfig", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Void> saveOrUpdateEmailNotifyConfig(@ModelAttribute UserNotifyConfigSaveVo userNotifyConfigSaveVo, HttpServletRequest request) {
        SysUser sysUser=this.getUser(request);
        userNotifyConfigSaveVo.setWay(0);
        userNotifyConfigService.saveOrUpdateNotifyConfig(sysUser.getUserId(),userNotifyConfigSaveVo);
        return ReturnResult.success("ok");
    }

    @ApiOperation("获取用户设置的邮箱通知数据")
    @RequestMapping(value = "/n/findEmailNotifyConfig", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<UserNotifyConfig> findEmailNotifyConfig( HttpServletRequest request) {
        SysUser sysUser=this.getUser(request);
        UserNotifyConfig userNotifyConfig = userNotifyConfigService.findNotifyConfigByUserIdWay(sysUser.getUserId(), 0);
        return ReturnResult.success(userNotifyConfig);
    }

    @ApiOperation("确定是否发送邮件")
    @RequestMapping(value = "/n/updateEmailNotifyConfigState", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<Void> updateEmailNotifyConfigState(@ApiParam("0不发送，1发送") @RequestParam("state") int state,HttpServletRequest request) {
        SysUser sysUser=this.getUser(request);
        userNotifyConfigService.updateEmailNotifyConfigState(sysUser.getUserId(), state);
        return ReturnResult.success("ok");
    }
}
